package test29.StreamAPI;

import org.junit.Test;
import test29.Lambda.Employee;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

/**
 * 测试Stream的中间操作
 */
public class StreamAPITest1 {
    //1-筛选与切片
    @Test
    public void test1() {
        //创建数
        List<Employee> list = EmployeeData.getEmployees();
        //filter(Predicate p)--接收Lambda ，从流中排除某些元素
        //创建Stream实例
        Stream<Employee> stream = list.stream();
        //条件查询
        stream.filter(employee -> employee.getSalary() > 7000).forEach(System.out::println);

        //limit(long maxSize) --截断流，使其元素不超过给定数量
        list.stream().limit(3).forEach(System.out::println);

        // skip(long n)--跳过元素，返回一个扔掉了前n 个元素的流。若流中元素不足n 个，则返回一个空流。与limit(n) 互补
        list.stream().skip(3).forEach(System.out::println);

        // distinct()--筛选，通过流所生成元素的hashCode() 和equals() 去除重复元素
        list.add(new Employee(100, "小刘", 40, 8000));
        list.add(new Employee(100, "小刘", 40, 8000));
        list.add(new Employee(100, "小刘", 40, 8000));
        list.add(new Employee(100, "小刘", 40, 8000));
        list.stream().distinct().forEach(System.out::println);
    }

    //2-映射
    @Test
    public void test2() {
        //map(Function f)
        List<String> list = Arrays.asList("aa", "bb", "cc", "dd");
        list.stream().map(str -> str.toUpperCase()).forEach(System.out::println);//把所有数据按照相关函数的转换，这里是转大写，AA  BB CC DD

        //练习：获取员工姓名长度大于3的员工的姓名
        List<Employee> employees = EmployeeData.getEmployees();
        Stream<String> namesStream = employees.stream().map(Employee::getName);
        namesStream.filter(name -> name.length() > 3).forEach(System.out::println);

        //练习2
        Stream<Stream<Character>> streamStream = list.stream().map(StreamAPITest1::formStringToStream);
        streamStream.forEach(s -> {
            s.forEach(System.out::println);
        });
        //flatMap(Function f)
        Stream<Character> characterStream = list.stream().flatMap(StreamAPITest1::formStringToStream);
        characterStream.forEach(System.out::println);
    }

    //将字符串中的多个字符构成的集合转换为对应的Stream的实例
    public static Stream<Character> formStringToStream(String str) {
        ArrayList<Character> list = new ArrayList<>();
        for (Character c : str.toCharArray()) {
            list.add(c);
        }
        return list.stream();
    }

    @Test
    public void test3() {
        //用ArrayList来理解flatMap(Function f)
        ArrayList list1 = new ArrayList();
        ArrayList list2 = new ArrayList();

        list1.add(1);
        list1.add(2);
        list1.add(3);
        list2.add(4);
        list2.add(5);
        list2.add(6);

        //list1.add(list2);  这个和list1.addAll的区别就类似map和flatMap
        list1.addAll(list2);
        System.out.println(list1);
    }

    //3-排序
    @Test
    public void test4() {
        //sorted()-（自然排序）
        List<Integer> list = Arrays.asList(12, 23, 4, 5, 67, 234, 0, 7, -1);
        list.stream().sorted().forEach(System.out::println);
        //抛异常，原因：Employee没有实现Comparable接口
//        List<Employee> employees = EmployeeData.getEmployees();
//        employees.stream().sorted().forEach(System.out::println);

        //sorted(Comparator com) -(定制排序)
        List<Employee> employees = EmployeeData.getEmployees();
        //employees.stream().sorted((e1,e2) -> Integer.compare(e1.getAge(),e2.getAge())).forEach(System.out::println);
        //按年龄排序，当年龄一样再按照薪水排序
        employees.stream().sorted((e1, e2) -> {
            int ageValue = Integer.compare(e1.getAge(),e2.getAge());
           if (ageValue != 0){
               return ageValue;
           }else {
               //return Double.compare(e1.getSalary(),e2.getSalary());
               //从大到小
               return -Double.compare(e1.getSalary(),e2.getSalary());
           }
        }).forEach(System.out::println);
    }
}
